package cn.xshi.bpm.service.impl;

import cn.xshi.bpm.model.LcApply;
import cn.xshi.bpm.model.LcDeploymentHis;
import cn.xshi.bpm.model.LcProcess;
import cn.xshi.bpm.param.LcReceiveNParam;
import cn.xshi.bpm.param.LcReceiveParam;
import cn.xshi.bpm.param.selfDefined.SelfDefinedStartParam;
import cn.xshi.bpm.service.*;
import cn.xshi.bpm.util.ActivitiUtil;
import cn.xshi.bpm.vo.ActivityProcessStatusEntity;
import cn.xshi.common.base.BaseResult;
import cn.xshi.common.base.BaseService;
import cn.xshi.common.util.ExceptionUtil;
import cn.xshi.common.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Desc 自定义处理流程流转服务
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
@Service
public class SelfDefinedServiceImpl extends BaseService implements SelfDefinedService {

    @Resource
    LcProcessService lcProcessService;

    @Resource
    LcDeploymentHisService lcDeploymentHisService;

    @Resource
    ActivitiUtil activitiUtil;

    @Resource
    LcTaskService lcTaskService;

    @Resource
    private LcApplyService lcApplyService;

    /**
     * 根据模块Key发起流程实例
     * @param selfDefinedStartParam
     * @return
     */
    public BaseResult<ActivityProcessStatusEntity> start(SelfDefinedStartParam selfDefinedStartParam){
        try {
            String moduleKey = selfDefinedStartParam.getModuleKey();
            LcProcess lcProcess = lcProcessService.getLcProcessByModuleKey(moduleKey);

            if(null == lcProcess){
                return BaseResult.fail("未能获取到模块key");
            }
            Map<String,Object> condition = new HashMap<>();
            condition.put("lcProcessId",lcProcess.getId());
            condition.put("version",selfDefinedStartParam.getVersion());//流程定义版本号 配合模块key使用（注意 如果版本号为空 则采用模块Key下最新流程定义）
            LcDeploymentHis lcDeploymentHis = lcDeploymentHisService.getLcDeploymentHisNewUnique(condition);//过滤条件为关闭状态
            if(null == lcDeploymentHis){
                return BaseResult.fail("未能获取到最新流程版本");
            }

            ProcessDefinition processDefinition = activitiUtil.getProcessDefinition(lcDeploymentHis.getDeploymentId());
            ProcessInstance processInstance = activitiUtil.startProcessInstanceByKey(processDefinition.getKey(), selfDefinedStartParam.getBusinessKey(), selfDefinedStartParam.getVariables());
            /**Activiti发起实例模块(即提交发起申请)开始**/
            /**调用审批工作流**/
            if(null != processInstance){
                LcApply lcApply = new LcApply();
                if(StringUtil.isEmpty(lcApply.getLcApplyId())){
                    lcApply.setLcApplyId(toUUID());
                }
                lcApply.setCreateTime(getDate());
                lcApply.setProcDefId(processDefinition.getId());
                lcApply.setProcInstId(processInstance.getId());
                lcApply.setTitle(selfDefinedStartParam.getTitle());
                lcApply.setBusinessKey(processInstance.getBusinessKey());
                lcApplyService.addLcApply(lcApply);
                ///////////根据当前实例编号查找第一个节点并设置发起人//////////////
                List<Task> tasks = activitiUtil.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).orderByTaskCreateTime().asc().list();
                if(null != tasks &&!tasks.isEmpty()){
                    Task task = tasks.get(0);
                    //设置当前任务为处理人即发起人
                    activitiUtil.setAssignee(task.getId(),selfDefinedStartParam.getMultiValue());

                    if(ActivitiUtil.ACT_CODE_10.equals(selfDefinedStartParam.getCompleted())){//需要完成第一个任务
                        doStartCompleteTask(task,selfDefinedStartParam);
                    }
                }
                log.debug("调用工作流审批信息模块成功");
                return new BaseResult(lcTaskService.checkStatus(processInstance.getProcessInstanceId()));
            }else{
                log.debug("调用工作流审批信息模块失败");
                return new BaseResult("-1",false);
            }
            /**Activiti发起实例模块(即提交发起申请)结束**/
        } catch (Exception e) {
            log.error("添加审批异常：{}",e);
            throw new ExceptionUtil(e.getMessage(),e.getCause());
        }
    }

    /**
     * 处理第一个节点
     * @param task
     */
    private void doStartCompleteTask(Task task,SelfDefinedStartParam selfDefinedStartParam){
        LcReceiveNParam lcReceiveNParam = new LcReceiveNParam();
        lcReceiveNParam.setTaskId(task.getId());
        lcReceiveNParam.setBehavior(activitiUtil.BEHAVIOR_0);//默认提交
        List<LcReceiveParam> lcReceiveParams = new ArrayList<>();
        LcReceiveParam lcReceiveParam = new LcReceiveParam();
        lcReceiveParam.setMultiValue(selfDefinedStartParam.getNextMultiValue());
        lcReceiveParams.add(lcReceiveParam);
        lcReceiveNParam.setLcReceiveParams(lcReceiveParams);
        lcTaskService.completeTask(lcReceiveNParam);
    }
}
